﻿using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Prism.Services.Dialogs;
using System.Collections.ObjectModel;
using Prism.Events;
using Simple_search.Service;
using Simple_search.Data;

namespace Simple_search.ViewModels
{
    public class OptionWindowViewModel : BindableBase, IDialogAware
    {
        private CacheManager _cacheManager;

        public OptionWindowViewModel(CacheManager cacheManager)
        {
            _cacheManager = cacheManager;
            if (_cacheManager.Options != null)
            {
                BookDirectory = _cacheManager.Options.BookDirectory;
                FileName = _cacheManager.Options.FileName;
                IsFuzzy = _cacheManager.Options.IsFuzzy;
                BlockSize = _cacheManager.Options.BlockSize.ToString();
            }
        }

        public string Title { get; } = "检索设置";

        private string bookDirectory = "";
        public string BookDirectory
        {
            get { return bookDirectory; }
            set
            {
                SetProperty(ref bookDirectory, value);
                CommandSubmit.RaiseCanExecuteChanged();
            }
        }

        private string fileName = "";
        public string FileName
        {
            get { return fileName; }
            set
            {
                SetProperty(ref fileName, value);
                CommandSubmit.RaiseCanExecuteChanged();
            }
        }

        private bool isFuzzy = true;
        public bool IsFuzzy
        {
            get { return isFuzzy; }
            set { SetProperty(ref isFuzzy, value); }
        }

        private int threshold;
        public int Threshold
        {
            get { return threshold; }
            set { SetProperty(ref threshold, value); }
        }


        private int blockSize = 100;
        public string BlockSize
        {
            get { return blockSize.ToString(); }
            set
            {
                SetProperty(ref blockSize, int.Parse(value));
                CommandSubmit.RaiseCanExecuteChanged();
            }
        }


        public ObservableCollection<int> Thresholds { get; } = new();

        private DelegateCommand commandSetBookDirectory;
        public DelegateCommand CommandSetBookDirectory =>
            commandSetBookDirectory ?? (commandSetBookDirectory = new DelegateCommand(ExecuteCommandSetBookDirectory));

        void ExecuteCommandSetBookDirectory()
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new();
            dialog.ShowNewFolderButton = true;
            System.Windows.Forms.DialogResult dialogResult = dialog.ShowDialog();
            if (dialogResult == System.Windows.Forms.DialogResult.OK)
            {
                BookDirectory = dialog.SelectedPath;
            }
        }

        private DelegateCommand commandSetFileName;
        public DelegateCommand CommandSetFileName =>
            commandSetFileName ?? (commandSetFileName = new DelegateCommand(ExecuteCommandSetFileName));

        void ExecuteCommandSetFileName()
        {
            Microsoft.Win32.SaveFileDialog dialog = new();
            dialog.FileName = "output";
            dialog.DefaultExt = "xlsx";
            dialog.Filter = "Excel Open XML Format(.xlsx)|*.xlsx";
            bool? result = dialog.ShowDialog();
            if (result == true)
            {
                FileName = dialog.FileName;
            }
        }

        private DelegateCommand commandSubmit;
        public DelegateCommand CommandSubmit =>
            commandSubmit ?? (commandSubmit = new DelegateCommand(ExecuteCommandSubmit, CanExecuteCommandSubmit));

        void ExecuteCommandSubmit()
        {
            Options options = new()
            {
                BookDirectory = bookDirectory,
                FileName = fileName,
                IsFuzzy = isFuzzy,
                BlockSize = blockSize
            };
            _cacheManager.UpdateOptions(options);
            DialogParameters parameters = new();
            parameters.Add("BookDirectory", bookDirectory);
            parameters.Add("FileName", fileName);
            parameters.Add("IsFuzzy", isFuzzy);
            parameters.Add("Threshold", threshold);
            parameters.Add("BlockSize", blockSize);
            RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));
        }

        bool CanExecuteCommandSubmit()
        {
            if (BookDirectory == "")
            {
                return false;
            }
            else if (!Directory.Exists(BookDirectory))
            {
                return false;
            }
            if (FileName == "")
            {
                return false;
            }
            else if (!Directory.Exists(Path.GetDirectoryName(FileName)))
            {
                return false;
            }
            else if (Path.GetExtension(FileName) != ".xlsx")
            {
                string extension = Path.GetExtension(FileName);
                return false;
            }
            if (BlockSize == "")
            {
                return false;
            }
            if (blockSize <= 10)
            {
                return false;
            }

            return true;
        }


        private DelegateCommand commandCancel;
        public DelegateCommand CommandCancel =>
            commandCancel ?? (commandCancel = new DelegateCommand(ExecuteCommandCancel));

        void ExecuteCommandCancel()
        {
            RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
        }

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            int searchUnitCount = parameters.GetValue<int>("SearchUnitCount");
            if (searchUnitCount > 1)
            {
                threshold = 2;
            } else
            {
                threshold = 1;
            }
            for (int i = 0; i < searchUnitCount; i++)
            {
                Thresholds.Add(i + 1);
            }

        }
    }
}
